"""
clang MCP Server

面向软件：clang (C/C++编译器)

MCP tools 列表：
- clang_version: 获取clang版本信息
  参数：无
  返回：{"success": bool, "command": str, "exit_code": int, "stdout": str, "stderr": str}

- clang_compile: 编译C/C++源文件
  参数：source_file (源文件路径), output_file (输出文件路径), options (编译选项列表)
  返回：{"success": bool, "command": str, "exit_code": int, "stdout": str, "stderr": str}

- clang_preprocess: 预处理源文件
  参数：source_file (源文件路径), output_file (输出文件路径), options (预处理选项列表)
  返回：{"success": bool, "command": str, "exit_code": int, "stdout": str, "stderr": str}

- clang_assembly: 生成汇编代码
  参数：source_file (源文件路径), output_file (输出文件路径), options (汇编选项列表)
  返回：{"success": bool, "command": str, "exit_code": int, "stdout": str, "stderr": str}

- clang_syntax_check: 语法检查
  参数：source_file (源文件路径), options (检查选项列表)
  返回：{"success": bool, "command": str, "exit_code": int, "stdout": str, "stderr": str}

- clang_show_includes: 显示包含的头文件
  参数：source_file (源文件路径), options (包含选项列表)
  返回：{"success": bool, "command": str, "exit_code": int, "stdout": str, "stderr": str}
"""

from mcp.server.fastmcp import FastMCP, Context
import subprocess
import shlex
from typing import List

mcp = FastMCP("Clang MCP Server")

@mcp.tool()
def clang_version() -> dict:
    """获取clang版本信息
    
    返回：
        dict: 包含执行结果的字典，结构为：
            {
                "success": bool,      # 是否成功执行
                "command": str,       # 执行的命令
                "exit_code": int,     # 退出码
                "stdout": str,        # 标准输出
                "stderr": str         # 标准错误
            }
    """
    cmd = "clang --version"
    try:
        result = subprocess.run(shlex.split(cmd), capture_output=True, text=True)
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": cmd,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def clang_compile(source_file: str, output_file: str = "a.out", options: List[str] = None) -> dict:
    """编译C/C++源文件
    
    参数：
        source_file: 源文件路径
        output_file: 输出文件路径，默认为a.out
        options: 编译选项列表，如["-O2", "-Wall"]
    
    返回：
        dict: 包含执行结果的字典
    """
    if options is None:
        options = []
    
    cmd_parts = ["clang", source_file, "-o", output_file] + options
    cmd = " ".join(cmd_parts)
    
    try:
        result = subprocess.run(cmd_parts, capture_output=True, text=True)
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": cmd,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def clang_preprocess(source_file: str, output_file: str = None, options: List[str] = None) -> dict:
    """预处理源文件
    
    参数：
        source_file: 源文件路径
        output_file: 输出文件路径，如不指定则输出到标准输出
        options: 预处理选项列表
    
    返回：
        dict: 包含执行结果的字典
    """
    if options is None:
        options = []
    
    cmd_parts = ["clang", "-E", source_file] + options
    if output_file:
        cmd_parts.extend(["-o", output_file])
    
    cmd = " ".join(cmd_parts)
    
    try:
        result = subprocess.run(cmd_parts, capture_output=True, text=True)
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": cmd,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def clang_assembly(source_file: str, output_file: str = None, options: List[str] = None) -> dict:
    """生成汇编代码
    
    参数：
        source_file: 源文件路径
        output_file: 输出文件路径，如不指定则输出到标准输出
        options: 汇编选项列表
    
    返回：
        dict: 包含执行结果的字典
    """
    if options is None:
        options = []
    
    cmd_parts = ["clang", "-S", source_file] + options
    if output_file:
        cmd_parts.extend(["-o", output_file])
    
    cmd = " ".join(cmd_parts)
    
    try:
        result = subprocess.run(cmd_parts, capture_output=True, text=True)
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": cmd,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def clang_syntax_check(source_file: str, options: List[str] = None) -> dict:
    """语法检查
    
    参数：
        source_file: 源文件路径
        options: 检查选项列表
    
    返回：
        dict: 包含执行结果的字典
    """
    if options is None:
        options = []
    
    cmd_parts = ["clang", "-fsyntax-only", source_file] + options
    cmd = " ".join(cmd_parts)
    
    try:
        result = subprocess.run(cmd_parts, capture_output=True, text=True)
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": cmd,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def clang_show_includes(source_file: str, options: List[str] = None) -> dict:
    """显示包含的头文件
    
    参数：
        source_file: 源文件路径
        options: 包含选项列表
    
    返回：
        dict: 包含执行结果的字典
    """
    if options is None:
        options = []
    
    cmd_parts = ["clang", "-H", source_file] + options
    cmd = " ".join(cmd_parts)
    
    try:
        result = subprocess.run(cmd_parts, capture_output=True, text=True)
        return {
            "success": result.returncode == 0,
            "command": cmd,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": cmd,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

if __name__ == "__main__":
    mcp.run()